﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Data.Objects;

namespace ElectronStoreDAL
{
	/// <summary>
	/// 
	/// </summary>
	public class ElectronStoreSource
	{
		private static ElectronStoreEntities esEntities;

		/// <summary>
		/// This
		/// </summary>
		public ElectronStoreEntities EsEntities
		{
			get
			{
				if (esEntities == null)
				{
					esEntities = new ElectronStoreEntities();
				}
				return esEntities;
			}
		}


		#region Product

		/// <summary>
		/// 
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		public Product GetProductById(int id)
		{
			Product product = EsEntities.Products.Where(x => x.ProductID == id).FirstOrDefault();
			return product;
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="idCategory"></param>
		/// <returns></returns>
		public int CountProduct(int idCategory)
		{
			Category category = EsEntities.Categories.Where(x => x.CategoryID == idCategory).FirstOrDefault();
			if (category != null)
				return category.Products.Count;
			else
				return 0;
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="idCategory"></param>
		/// <returns></returns>
		public List<Product> ProductsFromCategory(int idCategory)
		{
			Category category = EsEntities.Categories.Where(x => x.CategoryID == idCategory).FirstOrDefault();
			if (category != null)
				return EsEntities.Categories.Where(x => x.CategoryID == idCategory).First().Products.ToList();
			else
				return null;
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="idCategory"></param>
		/// <param name="start"></param>
		/// <param name="count"></param>
		/// <returns></returns>
		public List<Product> GetRangeProducts(int idCategory, int start, int count)
		{
			List<Product> list;
			Category category = EsEntities.Categories.Where(x => x.CategoryID == idCategory).FirstOrDefault();
			if (category != null)
			{
				list = EsEntities.Categories.Where(x => x.CategoryID == idCategory).First().Products.Skip(start).Take(count).ToList();
			}
			else
			{
				list = null;
			}

			return list;
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="product"></param>
		/// <returns></returns>
		public int AddProduct(Product product)
		{
			EsEntities.Products.AddObject(product);
			try
			{
				EsEntities.SaveChanges();
				return product.ProductID;
			}
			catch (Exception ex)
			{
				ErrorLogger.LogError(ex);
				return 0;
			}
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="product"></param>
		public void UpdateProduct(Product product)
		{
			if (product == null)
				return;
			try
			{
				try
				{
					EsEntities.SaveChanges();
				}
				catch (OptimisticConcurrencyException)
				{
					EsEntities.Refresh(RefreshMode.ClientWins, product);
				}
			}
			catch (UpdateException ex)
			{
				ErrorLogger.LogError(ex);
			}
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		public int RemoveProduct(int id)
		{
			Product product = EsEntities.Products.Where(x => x.ProductID == id).FirstOrDefault();
			if (product == null)
				return 0;

			EsEntities.Products.DeleteObject(product);
			try
			{
				EsEntities.SaveChanges();
				return id;
			}
			catch (Exception ex)
			{
				ErrorLogger.LogError(ex);
				return 0;
			}
		}


		/// <summary>
		/// Category category = EsEntities.Categories.Where(x => x.CategoryID == id).FirstOrDefault();
		/// </summary>
		/// <param name="idProduct"></param>
		/// <param name="idCategory"></param>
		/// <returns></returns>
		public int RemoveProductFromCategory(int idProduct, int idCategory)
		{
			Product product = EsEntities.Products.Where(x => x.ProductID == idProduct).FirstOrDefault();
			Category category = EsEntities.Categories.Where(x => x.CategoryID == idCategory).FirstOrDefault();
			try
			{
				if (product.Categories.Count == 1)
				{
					EsEntities.Products.DeleteObject(product);
				}
				else
				{
					product.Categories.Remove(category);
					category.Products.Remove(product);
				}
				EsEntities.SaveChanges();
				return idProduct;
			}
			catch (Exception ex)
			{
				ErrorLogger.LogError(ex);
				return 0;
			}
		}

		#endregion


		#region Category

		/// <summary>
		/// 
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		public Category GetCategoryById(int id)
		{
			Category category = EsEntities.Categories.Where(x => x.CategoryID == id).FirstOrDefault();
			return category;
		}


		/// <summary>
		///  
		/// </summary>
		/// <returns></returns>
		public List<Category> GetCategories()
		{
			return EsEntities.Categories.ToList();
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="category"></param>
		/// <returns></returns>
		public int AddCategory(Category category)
		{
			EsEntities.Categories.AddObject(category);
			try
			{
				EsEntities.SaveChanges();
				return category.CategoryID;
			}
			catch (Exception ex)
			{
				ErrorLogger.LogError(ex);
				return 0;
			}
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="category"></param>
		public void UpdateCategory(Category category)
		{
				if (category == null)
					return;
			try
			{
				try
				{
					EsEntities.SaveChanges();
				}
				catch (OptimisticConcurrencyException)
				{
					EsEntities.Refresh(RefreshMode.ClientWins, category);
				}
			}
			catch (UpdateException ex)
			{
				ErrorLogger.LogError(ex);
			}
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		public int RemoveCategory(int id)
		{
			Category category = EsEntities.Categories.Where(x => x.CategoryID == id).FirstOrDefault();
			if (category == null)
				return 0;

			foreach (var product in category.Products)
			{
				if(product.Categories.Count == 1)
					EsEntities.Products.DeleteObject(product);
			}
			EsEntities.Categories.DeleteObject(category);

			try
			{
				EsEntities.SaveChanges();
				return id;
			}
			catch (Exception ex)
			{
				ErrorLogger.LogError(ex);
				return 0;
			}
		}


		public void RemoveCategoryFromProduct()
		{

		}

		#endregion

	}   //public class ElectronStoreSource

}	//namespace ElectronStoreDAL






